package com.example.source_share.controller.file;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.source_share.mapper.FileMapper;
import com.example.source_share.mapper.UserMapper;
import com.example.source_share.pojo.Files;
import com.example.source_share.pojo.User;
import com.example.source_share.service.file.FileUploadService;
import com.example.source_share.service.user.account.InfoService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileSystemUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.*;

@RestController
public class FileController {
    @Autowired
    private FileUploadService fileUploadService;
    @Autowired
    private FileMapper fileMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private InfoService infoService;
    public static String formatFileSize(long size) {//计算文件大小的中间函数
        if (size <= 0) {
            return "0B";
        }
        String[] units = {"B", "KB", "MB"};
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
        DecimalFormat decimalFormat = new DecimalFormat("#,##0.#");
        return decimalFormat.format(size / Math.pow(1024, digitGroups)) + units[digitGroups];
    }
    @PostMapping("/file/upload") //post传送文件，实现上传
    public Map<String, String> getFile(@RequestPart("file") MultipartFile file,
                                       @RequestPart("college") String college,
                                       @RequestPart("major") String major,
                                       @RequestPart("subject") String subject,
                                       @RequestPart("grade") String grade,
                                       @RequestPart("year") String year,
                                       @RequestPart("description") String description,
                                       @RequestHeader("Authorization") String authorizationHeader) throws IOException {
        //头部
        //System.out.println("Authorization: " + authorizationHeader);
        System.out.println("---------------------------------");
        System.out.println("新文件上传");
        Map<String,String> author=infoService.getinfo();
        System.out.println("上传者为:"+author.get("name"));
        //测试用System.out.println(college+major+subject+description+grade+year);
        if(file==null){
            Map<String,String> map = new HashMap<>();
            map.put("message","未选择文件");
            return map;
        }
        if(!file.isEmpty())
        {
            // 获取文件名
            // 验证是否存在
            System.out.println("文件名为:"+file.getOriginalFilename());
            QueryWrapper<Files> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("filename",file.getOriginalFilename());
            Files exist=fileMapper.selectOne(queryWrapper);
            if(exist!=null) {
                Map<String,String> map = new HashMap<>();
                System.out.println("文件已被阻拦，原因：文件名重复");
                map.put("message","文件重复");
                return map;
            }
            // 获取原始文件路径
            // 文件存储
            File file1 = new File("G:/VUE/data/"+file.getOriginalFilename());
            //文件大小
            long fileSize = file.getSize(); // 获取文件大小，以字节为单位
            String size=formatFileSize(fileSize);
            System.out.println("文件大小: " + fileSize + " bytes");
            //少量参数构造Files newfile=new Files(file.getOriginalFilename(),size,author.get("name"),file1.getPath());
            //全参数构造Files
            Files newfile=new Files(file.getOriginalFilename(),size,
                    major, subject,
                    author.get("name"), description, description,file1.getPath(),grade,year);
            fileMapper.insert(newfile);
            FileOutputStream stream = new FileOutputStream(file1);
            byte[] bytes = file.getBytes();
            stream.write(bytes);
            stream.close();
            //更新贡献数
            //找出所有该作者的所有文档
            QueryWrapper<Files> queryWrapper0=new QueryWrapper<>();
            queryWrapper0.eq("author",author.get("name"));
            //找出所有该作者的user表中数据
            QueryWrapper<User> queryWrapper1=new QueryWrapper<>();
            queryWrapper1.eq("username",author.get("name"));
            //使用up修改贡献量
            User up=userMapper.selectOne(queryWrapper1);
            //System.out.println("贡献"+fileMapper.selectList(queryWrapper0).size());
            //更新
            up.setContributions(fileMapper.selectList(queryWrapper0).size());
            //这里还要通过id对应数据库中的项，然后使用update方法存储到数据库中
            QueryWrapper<User> updateWrapper=new QueryWrapper<>();
            updateWrapper.eq("userid",up.getUserid());
            userMapper.update(up,updateWrapper);
            return fileUploadService.addToFiles(file);//返回成功以及文件信息
        }
        else
        {
            Map<String,String> map = new HashMap<>();
            map.put("message","空文件");
            return map;
        }
    }
    @GetMapping("/file/all") //获取全部文件
    public List<Files> getAll(){ //获取全部用户
        return fileMapper.selectList(null);
    }
    @GetMapping("/file/info/{filename}") //获取单个文件信息
    public Files getInfo(@PathVariable String filename){
        //System.out.println(filename);
        QueryWrapper<Files> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("filename",filename);
        return fileMapper.selectOne(queryWrapper);
    }

    @GetMapping("/file/download/{fileDownload}")//传入参数文件名，实现下载
    @ResponseBody
    public String downLoad (HttpServletRequest request, HttpServletResponse response, @PathVariable String fileDownload) throws IOException {
        //先判断文件是否存在
        QueryWrapper<Files> queryWrapper=new QueryWrapper<>();
        Map<String,String> map=new HashMap<>();
        queryWrapper.eq("filename",fileDownload);
        Files exist=fileMapper.selectOne(queryWrapper);
        if(exist==null) {
            return "文件不存在";
        }
        String realPath = exist.getFilepath();
        File file = new File(realPath);
        String filename = file.getName();
        //此处下载流的代码块参考https://blog.csdn.net/sunabeng/article/details/107870435
        // 设置浏览器以下载方式打开， 此处不设置，会直接在浏览器预览图片
        response.setHeader("content-disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
        // 读取文件，写到输出流
        InputStream in = new FileInputStream(file);
        byte[] buf = new byte[1024];
        while (in.read(buf) > 0) {
            response.getOutputStream().write(buf, 0, buf.length);
        }
        in.close();
        //更新下载量
        exist.setDownload(exist.getDownload() + 1);
        fileMapper.update(exist,queryWrapper);
        return "Success!";
    }
    /*
    private String getContentType(String filename) { //获取文件类型的函数
        String contentType;
        String extension = filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
        contentType = switch (extension) {
            case "pdf" -> "application/pdf";
            case "doc" -> "application/msword";
            case "docx" -> "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
            case "xls" -> "application/vnd.ms-excel";
            case "xlsx" -> "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            case "ppt" -> "application/vnd.ms-powerpoint";
            case "pptx" -> "application/vnd.openxmlformats-officedocument.presentationml.presentation";
            default -> "application/octet-stream";
        };
        return contentType;
    }
    @GetMapping("/file/preview/{fileDownload}")//传入参数文件名，实现预览
    @ResponseBody
    public void previewFile(HttpServletRequest request, HttpServletResponse response, @PathVariable String fileDownload) throws IOException {
        // 先判断文件是否存在
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("filename", fileDownload);
        Files exist = fileMapper.selectOne(queryWrapper);
        if (exist == null) {
            response.getWriter().write("文件不存在");
            return;
        }
        String realPath = exist.getFilepath();
        File file = new File(realPath);
        String filename = file.getName();
        String contentType = getContentType(filename);

        // 设置响应头
        response.setHeader("Content-Type", contentType);

        // 读取文件，写到输出流
        InputStream in = new FileInputStream(file);
        OutputStream out = response.getOutputStream();
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();
    }
    */
    @PostMapping("/file/myfile") //返回我的文件
    public List<Files> getMine(@RequestHeader("Authorization") String authorizationHeader) {
        Map<String,String> author=infoService.getinfo();
        QueryWrapper<Files> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("author",author.get("name"));
        return fileMapper.selectList(queryWrapper);
    }
    @PostMapping("/file/delete") //删除文件
    public Map<String,String> del(@RequestParam String filename,@RequestHeader("Authorization") String authorizationHeader) {
        Map<String,String> nowLogin=infoService.getinfo(); //需要用户本人或者管理员才能删除，判定token
        Map<String,String> result= new HashMap<>();
        QueryWrapper<Files> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("filename",filename);
        Files nowFile=fileMapper.selectOne(queryWrapper); //找出目前的文件
        String author=nowFile.getAuthor(); //找出作者
        System.out.println("---------------------------------");
        System.out.println("正在执行删除操作的是："+nowLogin);
        System.out.println("文件名为："+filename);
        System.out.println("文件作者是"+author);
        if(!Objects.equals(nowLogin.get("purview"), "Super Admin") && !Objects.equals(author, nowLogin.get("name"))){
            result.put("message","权限不足!");
            return result;
        }
        //执行删除操作
        String filepath = nowFile.getFilepath(); //路径
        FileSystemUtils.deleteRecursively(new File(filepath)); //删除本地文件
        fileMapper.delete(queryWrapper); //删除数据库数据
        result.put("message","Success!");
        return result;
    }
    @GetMapping("/file/hot") //获取最热门文件
    public List<String> getHot(){ //获取全部用户
        QueryWrapper<Files> queryWrapper=new QueryWrapper<>();
        queryWrapper.orderByDesc("download");
        List<Files> hotFile=fileMapper.selectList(queryWrapper);
        List<String> result=new ArrayList<>();
        int limit=3;//返回的文件数
        for(int i=0;i<limit;i++){
            result.add(hotFile.get(i).getFilename());
        }
        return result;
    }
    @GetMapping("/file/new") //获取最新文件
    public List<String> getNew(){
        QueryWrapper<Files> queryWrapper=new QueryWrapper<>();
        queryWrapper.orderByDesc("fileid");
        List<Files> hotFile=fileMapper.selectList(queryWrapper);
        List<String> result=new ArrayList<>();
        int limit=3;//返回的文件数
        for(int i=0;i<limit;i++){
            result.add(hotFile.get(i).getFilename());
        }
        return result;
    }
}